/**
 * There are <a href="https://github.com/thinkgem/jeesite">JeeSite</a> code generation
 */
package com.thinkgem.jeesite.modules.bls.web;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.ConstraintViolationException;

import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.google.common.collect.Lists;
import com.thinkgem.jeesite.common.beanvalidator.BeanValidators;
import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.mapper.JsonMapper;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.utils.DateUtils;
import com.thinkgem.jeesite.common.utils.excel.ExportExcel;
import com.thinkgem.jeesite.common.utils.excel.ImportExcel;
import com.thinkgem.jeesite.common.web.BaseController;
import com.thinkgem.jeesite.modules.bls.entity.Loan;
import com.thinkgem.jeesite.modules.bls.service.LoanService;
import com.thinkgem.jeesite.modules.sys.entity.User;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;
import com.thinkgem.jeesite.modules.sys.utils.workflow.Variable;

/**
 * 信贷分析Controller
 * 
 * @author edpdennis
 * @version 2013-04-19
 */
@Controller
@RequestMapping(value = Global.ADMIN_PATH + "/bls/loan")
public class LoanController extends BaseController {

	@Autowired
	private LoanService loanService;
	@Autowired
	protected RuntimeService runtimeService;
	@Autowired
	protected TaskService taskService;
	
	private static org.slf4j.Logger logger = LoggerFactory
			.getLogger(LoanController.class);

	@ModelAttribute
	public Loan get(@RequestParam(required = false) Long id) {
		if (id != null) {
			return loanService.get(id);
		} else {
			return new Loan();
		}
	}

	@RequiresPermissions("bls:loan:view")
	@RequestMapping(value = { "list", "" })
	public String list(Loan loan, HttpServletRequest request,
			HttpServletResponse response, Model model) {
		
		Page<Loan> page = loanService.find(new Page<Loan>(request, response),
				loan);
		model.addAttribute("page", page);
		return "modules/bls/loanList";
	}

	@RequiresPermissions("bls:loan:view")
	@RequestMapping(value = "form")
	public String form(Loan loan, Model model) {
		model.addAttribute("loan", loan);
		return "modules/bls/loanForm";
	}

	@RequiresPermissions("bls:loan:edit")
	@RequestMapping(value = "save")
	public String save(Loan loan, Model model,
			RedirectAttributes redirectAttributes) {
		if (!beanValidator(model, loan)) {
			return form(loan, model);
		}
		try {
			User user = UserUtils.getUser();
			loan.setUser(user);
			Map<String, Object> variables = new HashMap<String, Object>();
			ProcessInstance processInstance = loanService.startWorkflow(loan, variables);
			addMessage(redirectAttributes, "流程已启动，流程ID：" + processInstance.getId());
		} catch (Exception e) {
			logger.error("启动请假流程失败：", e);
			addMessage(redirectAttributes, "系统内部错误！");
		}
		
		//loanService.save(loan);
		//addMessage(redirectAttributes, "保存信贷分析'" + loan.getOfficerid() + "'成功");
		return "redirect:" + Global.ADMIN_PATH + "/bls/loan/?repage";
	}

	@RequiresPermissions("bls:loan:edit")
	@RequestMapping(value = "delete")
	public String delete(Long id, RedirectAttributes redirectAttributes) {
		loanService.delete(id);
		addMessage(redirectAttributes, "删除信贷分析成功");
		return "redirect:" + Global.ADMIN_PATH + "/bls/loan/?repage";
	}

	@RequiresPermissions("bls:loan:view")
	@RequestMapping(value = "export", method = RequestMethod.POST)
	public String exportFile(Loan loan, HttpServletRequest request,
			HttpServletResponse response, RedirectAttributes redirectAttributes) {
		try {
			String fileName = "信贷数据" + DateUtils.getDate("yyyyMMddHHmmss")
					+ ".xlsx";
			Page<Loan> page = loanService.find(
					new Page<Loan>(request, response), loan);

			new ExportExcel("信贷数据", Loan.class).setDataList(page.getList())
					.write(response, fileName).dispose();
			return null;
		} catch (Exception e) {
			addMessage(redirectAttributes, "导出信贷失败！失败信息：" + e.getMessage());
		}
		return "redirect:" + Global.ADMIN_PATH + "/bls/loan/?repage";
	}

	@RequiresPermissions("bls:loan:edit")
	@RequestMapping(value = "import", method = RequestMethod.POST)
	public String importFile(MultipartFile file,
			RedirectAttributes redirectAttributes) {
		try {
			int successNum = 0;
			int failureNum = 0;
			StringBuilder failureMsg = new StringBuilder();
			ImportExcel ei = new ImportExcel(file, 1, 0);
			List<Loan> list = ei.getDataList(Loan.class);
		
			for (Loan loan : list) {
				try {
					if ("true".equals("true")) {
						
						BeanValidators.validateWithException(validator, loan);
					
						loanService.save(loan);
					
						successNum++;
					} else {
						failureMsg.append("<br/>信贷录入员 " +  loan.getUser().getId()
								+ " 已存在; ");
						failureNum++;
					}
				} catch (ConstraintViolationException ex) {

					logger.info("<br/>信贷录入员 " +  loan.getUser().getId()+ " 导入失败：");
					failureMsg.append("<br/>信贷录入员 " + loan.getUser().getId()
							+ " 导入失败：");
					List<String> messageList = BeanValidators
							.extractPropertyAndMessageAsList(ex, ": ");
					for (String message : messageList) {
						failureMsg.append(message + "; ");
						failureNum++;
					}				 
				} catch (Exception ex) {
					failureMsg.append("<br/>信贷录入员 " +  loan.getUser().getId()
							+ " 导入失败：" + ex.getMessage());
				}
			}
			if (failureNum > 0) {
				failureMsg.insert(0, "，失败 " + failureNum + " 条信贷，导入信息如下：");
			}
			addMessage(redirectAttributes, "已成功导入 " + successNum + " 条信贷"
					+ failureMsg);
		} catch (Exception e) {
			addMessage(redirectAttributes, "导入信贷失败！失败信息：" + e.getMessage());
		}
		return "redirect:" + Global.ADMIN_PATH + "/bls/loan/?repage";
	}

	@RequiresPermissions("sys:loan:view")
	@RequestMapping(value = "import/template")
	public String importFileTemplate(HttpServletResponse response,
			RedirectAttributes redirectAttributes) {
		try {
			String fileName = "信贷数据导入模板.xlsx";
			List<Loan> list = Lists.newArrayList();
			list.add(loanService.get(1L));
			new ExportExcel("信贷数据", Loan.class, 2).setDataList(list)
					.write(response, fileName).dispose();
			return null;
		} catch (Exception e) {
			addMessage(redirectAttributes, "导入模板下载失败！失败信息：" + e.getMessage());
		}
		return "redirect:" + Global.ADMIN_PATH + "/bls/loan/?repage";
	}
	
	/**
	 * 任务列表
	 * @param leave	
	 */
	@RequiresPermissions("bls:loan:view")
	@RequestMapping(value = "list/task")
	public ModelAndView taskList(HttpSession session) {
		ModelAndView mav = new ModelAndView("modules/bls/loanTask");
		String userId = ObjectUtils.toString(UserUtils.getUser().getId());
		List<Loan> results = loanService.findTodoTasks(userId);
		mav.addObject("loans", results);
		return mav;
	}

	/**
	 * 读取运行中的流程实例
	 * @return
	 */
	@RequestMapping(value = "list/running")
	public ModelAndView runningList() {
		ModelAndView mav = new ModelAndView("modules/bls/loanRunning");
		List<Loan> results = loanService.findRunningProcessInstaces();
		mav.addObject("loans", results);
		return mav;
	}

	/**
	 * 读取已完成的流程实例
	 * @return
	 */
	@RequestMapping(value = "list/finished")
	public ModelAndView finishedList() {
		ModelAndView mav = new ModelAndView("modules/bls/loanFinished");
		List<Loan> results = loanService.findFinishedProcessInstaces();
		mav.addObject("loans", results);
		return mav;
	}

	/**
	 * 签收任务
	 */
	@RequestMapping(value = "task/claim/{id}")
	public String claim(@PathVariable("id") String taskId, HttpSession session, RedirectAttributes redirectAttributes) {
		String userId = ObjectUtils.toString(UserUtils.getUser().getId());
		taskService.claim(taskId, userId);
		redirectAttributes.addFlashAttribute("message", "任务已签收");
		return "redirect:"+Global.ADMIN_PATH+ "/bls/loan/list/task";
	}

	/**
	 * 读取详细数据
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "detail/{id}")
	@ResponseBody
	public String getLeave(@PathVariable("id") Long id) {
		Loan loan = loanService.get(id);
		
		logger.debug(JsonMapper.getInstance().toJson(loan).toString());
		return JsonMapper.getInstance().toJson(loan);
	
	}


	/**
	 * 读取详细数据
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "detail-with-vars/{id}/{taskId}")
	@ResponseBody
	public String getLeaveWithVars(@PathVariable("id") Long id, @PathVariable("taskId") String taskId) {
		Loan loan = loanService.get(id);
		Map<String, Object> variables = taskService.getVariables(taskId);
		loan.setVariables(variables);
		return JsonMapper.getInstance().toJson(loan);
	}

	/**
	 * 完成任务
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "complete/{id}", method = { RequestMethod.POST, RequestMethod.GET })
	@ResponseBody
	public String complete(@PathVariable("id") String taskId, Variable var) {
		try {
			Map<String, Object> variables = var.getVariableMap();
			taskService.complete(taskId, variables);
			return "success";
		} catch (Exception e) {
			logger.error("error on complete task {}, variables={}", new Object[] { taskId, var.getVariableMap(), e });
			return "error";
		}
	}
}
